import { FC, useCallback, useMemo, useState } from 'react'
import { DynamicColors, GStyleSheet } from '@/utils/DarkMode';
import { ISchedulerConfig, DataType, ComponentType } from '@/config/product'
import ListItem from '@/components/ListItem'
import BottomAlert from '@/components/Alert/BottomAlert'
import { View, Text, Image, Input } from '@tarojs/components'
import checkIcon from '@/assets/images/checkIcon.png'
import increaseIcon from '@/assets/images/icon_increase.png'
import reduceIcon from '@/assets/images/icon_reduce.png'
import {
  getSchedulerName,
  getSchedulerOptionNameByValue,
  getSchedulerOptionName,
  getSchedulerNumberTextByValue,
  getSchedulerUnit
} from '../utils/scheduleConfig'
import GSlider from '../components/GSlider'


interface IProps {
  schedule: ISchedulerConfig
  value: any
  onChange: ({ schedule, value }: { schedule: ISchedulerConfig, value: any }) => void
}

interface IAlertInfo {
  currentValue: any
  visiable: boolean
}

const SchedulerOptItem: FC<IProps> = ({ schedule, value, onChange }) => {
  const styles = dstyles.useDynamicStyle();
  const [alertInfo, setAlertInfo] = useState<IAlertInfo>({ currentValue: value, visiable: false })
  console.log('SchedulerOptItem', schedule, value)
  const { scheduleName, unit } = useMemo(() => {
    return {
      scheduleName: getSchedulerName({ scheduleConfig: schedule }),
      unit: getSchedulerUnit({ scheduleConfig: schedule })
    }
  }, [schedule])

  const isNumber = useMemo(() => {
    return schedule.dataType === DataType.Number
  }, [schedule.dataType])

  const valueText = useMemo(() => {
    return isNumber ? getSchedulerNumberTextByValue({ scheduleConfig: schedule, value }) : getSchedulerOptionNameByValue({ scheduleConfig: schedule, value })
  }, [value, schedule, isNumber])

  const hideAlert = useCallback(() => {
    setAlertInfo(v => ({ ...v, visiable: false }))
  }, [])

  const showAlert = useCallback(() => {
    setAlertInfo({ currentValue: value, visiable: true })
  }, [value])

  const onConfirm = useCallback((v: any) => {
    hideAlert()
    onChange({ schedule, value: v })
  }, [onChange, hideAlert, schedule])

  const changeCurrentValue = useCallback((v: number) => {
    setAlertInfo(a => ({ ...a, currentValue: v }))
  }, [])

  const onInput = useCallback(({ v, }: { v: string }) => {
    const num = parseInt(v, 10)
    changeCurrentValue(num)
  }, [changeCurrentValue])

  const checkInput = useCallback(({ v, min, max }: { min: number, max: number, v: string }) => {
    const num = parseInt(v, 10)
    if (num <= min) {
      changeCurrentValue(min)
    } else if (num >= max) {
      changeCurrentValue(max)
    } else {
      changeCurrentValue(num)
    }
  }, [changeCurrentValue])

  const renderOptionsList = useCallback(() => {
    return <View>
      {schedule.options?.map((opt) => {
        const isActive = alertInfo.currentValue === opt.value
        return (
          <ListItem
            key={opt.label}
            extraStyle={{ flex: undefined }}
            contentStyle={{ flex: 1, justifyContent: 'center' }}
            onPress={() => onConfirm(opt.value)}
          >
            <View className='centerFlex' style={{ flex: 1 }}>
              <View style={styles.checkIcon} />
              <View style={{ flex: 1, textAlign: 'center' }}>
                {getSchedulerOptionName({ option: opt })}
              </View>
              {isActive ? <Image src={checkIcon} style={styles.checkIcon} /> : <View style={styles.checkIcon} />}
            </View>
          </ListItem>
        )
      })}
    </View>
  }, [alertInfo.currentValue, schedule.options, styles.checkIcon, onConfirm])

  const renderNumberSelect = useCallback(() => {
    const step = schedule.step ?? 1
    const min = schedule.min ?? 0
    const max = schedule.max ?? 100
    const curValue = alertInfo.currentValue
    const isInput = schedule.componentType === ComponentType.Input
    return isInput ?
      <View style={styles.numberInputView}>
        <View className='centerFlex' style={{ justifyContent: "space-between" }}>
          <Text>{scheduleName}</Text>
          <View className='centerFlex' style={{ justifyContent: "flex-end" }}>
            <Input
              style={styles.input}
              placeholder='请输入'
              type='digit'
              value={curValue ? `${curValue}` : undefined}
              onInput={(e) => onInput({ v: e.detail.value })}
              onConfirm={() => checkInput({ v: curValue, min, max })}
              onBlur={() => checkInput({ v: curValue, min, max })}
            />
            <Text style={styles.value}>{unit}</Text>
          </View>
        </View>
      </View> : <View style={styles.numberView}>
        <View>
          <Text>{scheduleName}</Text>
          <Text style={styles.value}>{getSchedulerNumberTextByValue({ scheduleConfig: schedule, value: curValue })}</Text>
        </View>
        <View className='centerFlex'>
          <Image src={reduceIcon} style={styles.addButton} onClick={() => { changeCurrentValue(curValue - step <= min ? min : curValue - step) }} />
          <View style={styles.sliderView}>
            <GSlider
              onChange={(v) => changeCurrentValue(v)}
              value={curValue}
              min={min}
              max={max}
              radiusType='rectangle'
              indicator='point'
              step={step}
              showValue={false}
            />
          </View>
          <Image src={increaseIcon} style={styles.addButton} onClick={() => { changeCurrentValue(curValue + step >= max ? max : curValue + step) }} />
        </View>
      </View>
  }, [alertInfo.currentValue, changeCurrentValue, styles, schedule, scheduleName, unit, onInput, checkInput])


  return (
    <>
      <ListItem
        arrow
        onPress={showAlert}
        extra={<Text style={styles.text}>{valueText}</Text>}
      >
        {scheduleName}
      </ListItem>
      <BottomAlert
        isOpened={alertInfo.visiable}
        onCancel={hideAlert}
        showConfirm={isNumber}
        onConfirm={() => onConfirm(alertInfo.currentValue)}
      >
        {isNumber ? renderNumberSelect() : renderOptionsList()}
      </BottomAlert>
    </>
  )
}

const dstyles = GStyleSheet.create({
  container: {},
  text: { fontSize: 15, color: '#333', fontWeight: 400 },
  checkIcon: { width: 20, height: 20 },
  addButton: { width: 30, height: 30 },
  numberInputView: { padding: 40 },
  numberView: { padding: 20 },
  sliderView: { flex: 1, marginLeft: 15, marginRight: 15 },
  value: { color: DynamicColors.tintColor, fontSize: 14, marginLeft: 20 },
  input: { padding: 5, borderColor: DynamicColors.borderBottomColor, borderWidth: 1, borderStyle: 'solid', width: 100 }
});

export default SchedulerOptItem
